/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include "ViewWithMouseEventComponentInstance.h"
#include "generated/_hadss_react_native_uni_input/react/renderer/components/_hadss_react_native_uni_input/EventEmitters.h"
#include <arkui/ui_input_event.h>
#include <arkui/native_key_event.h>
#include <iostream>
#include <sstream>

using namespace std;

static const std::map<ArkUI_KeyEventType, std::string> KEY_EVENT_TYPE_MAP = {
    {ARKUI_KEY_EVENT_DOWN, "down"}, {ARKUI_KEY_EVENT_UNKNOWN, "unknown"},
    {ARKUI_KEY_EVENT_UP, "up"}, {ARKUI_KEY_EVENT_LONG_PRESS, "longPress"},
    {ARKUI_KEY_EVENT_CLICK, "click"}};

static const std::map<ArkUI_KeySourceType, std::string> KEY_SOURCE_TYPE_MAP = {
    {ARKUI_KEY_SOURCE_TYPE_MOUSE, "mouse"}, {ARKUI_KEY_SOURCE_UNKNOWN, "unknown"},
    {ARKUI_KEY_SOURCE_TYPE_KEYBOARD, "keyBoard"}, {ARKUI_KEY_SOURCE_TYPE_JOYSTICK, "joyStick"}};

namespace rnoh {
void ViewWithMouseEventComponentInstance::ReceiveEventStatic(ArkUI_NodeEvent *event)
{
    void *userData = OH_ArkUI_NodeEvent_GetUserData(event);
    if (userData) {
        auto instance = static_cast<ViewWithMouseEventComponentInstance *>(userData);
        instance->ReceiveEvent(event);
    }
}

void ViewWithMouseEventComponentInstance::ReceiveEvent(ArkUI_NodeEvent *event)
{
    try {
        auto eventType = OH_ArkUI_NodeEvent_GetEventType(event);
        ArkUI_UIInputEvent *inputEvent = OH_ArkUI_NodeEvent_GetInputEvent(event);
        if (eventType == NODE_ON_MOUSE) {
            facebook::react::ViewWithMouseEventEventEmitter::OnMouseEvent gEvent;
            gEvent.x = OH_ArkUI_PointerEvent_GetX(inputEvent);
            gEvent.y = OH_ArkUI_PointerEvent_GetY(inputEvent);
            gEvent.windowX = OH_ArkUI_PointerEvent_GetWindowX(inputEvent);
            gEvent.windowY = OH_ArkUI_PointerEvent_GetWindowY(inputEvent);
            gEvent.displayX = OH_ArkUI_PointerEvent_GetDisplayX(inputEvent);
            gEvent.displayY = OH_ArkUI_PointerEvent_GetDisplayY(inputEvent);
            gEvent.rawDeltaX = OH_ArkUI_MouseEvent_GetRawDeltaX(inputEvent);
            gEvent.rawDeltaY = OH_ArkUI_MouseEvent_GetRawDeltaY(inputEvent);
            gEvent.action = OH_ArkUI_UIInputEvent_GetAction(inputEvent);
            gEvent.button = OH_ArkUI_MouseEvent_GetMouseButton(inputEvent);
            m_eventEmitter->onMouseEvent(gEvent);
        }
    } catch (std::exception &e) {
        LOG(ERROR) << e.what();
    }
}

ViewWithMouseEventComponentInstance::ViewWithMouseEventComponentInstance(Context context) : Super(std::move(context))
{
    m_columnNode.setColumnNodeDelegate(this);
    NativeNodeApi::getInstance()->registerNodeEvent(m_columnNode.getArkUINodeHandle(), NODE_ON_MOUSE,
                                                    NODE_ON_MOUSE, this);
    NativeNodeApi::getInstance()->addNodeEventReceiver(m_columnNode.getArkUINodeHandle(),
                                                       &ViewWithMouseEventComponentInstance::ReceiveEventStatic);
}

ColumnNode &ViewWithMouseEventComponentInstance::getLocalRootArkUINode() { return m_columnNode; }

void ViewWithMouseEventComponentInstance::onPropsChanged(SharedConcreteProps const &props) {}

void ViewWithMouseEventComponentInstance::onChildInserted(ComponentInstance::Shared const &childComponentInstance,
                                                          std::size_t index)
{
    CppComponentInstance::onChildInserted(childComponentInstance, index);
    m_columnNode.insertChild(childComponentInstance->getLocalRootArkUINode(), index);
}

void ViewWithMouseEventComponentInstance::onChildRemoved(ComponentInstance::Shared const &childComponentInstance)
{
    CppComponentInstance::onChildRemoved(childComponentInstance);
    m_columnNode.removeChild(childComponentInstance->getLocalRootArkUINode());
}
} // namespace rnoh
